本文同步於個人部落格: Simplifying Conditional Logic
This article references the chapter 10 ” Simplifying Conditional Logic ” of Refactoring: Improving the Design of Existing Code (2nd Edition). Author had highlighted many important refactorings in this chapter.
I use .NET C# to practice with these refactorings and upload to Github.
(Photo from Pixabay: https://pixabay.com/illustrations/direction-path-decision-goal-2320124/)
Decompose Conditional
Tips
- If the condition is complex, extract the condition and its branches as functions.
Examples:
Github
Consolidate Conditional Expression
Tips
- Some conditions can be reduced into an “Ands” or “Ors” expression. Then this “Ands” or “Ors” expression can be extracted as a function.
- Sequences combine with Or, nested if statements combine with And.
- If the conditions have side-effect, use Separate Query from Modifier to process it.
Examples:
- An Ors example
- An Ands example
Github
Replace Nested Conditional with Guard Clauses
Tips
- If a condition is not normal, check it and return if it’s true. This check is a Guard Clause
- Guard Clause means that it is not the core logic of the function But if it happens, it does the necessary cleaning job to exit the function.
- Choose the outermost condition and replace it by Guard Clause. If some Guard Clauses have the same result, use Consolidate Conditional Expression.
Examples:
- An simple example
- Reversing the Conditions example
Github
Replace Conditional with Polymorphism
Tips
- If a condition is complex, split it by using polymorphism and make its logic clear
- For a variation condition, we put the basic logic into a superclass, and put the variation logic into derived class.
- Don’t abuse using polymorphism when the condition is simple.
- If the current class has no polymorphism, we create a factory function to return its object instance. Then we put every condition logic into derived class.
Examples:
- An simple example
- Using Polymorphism for Variation
Github
Introduce Special Case
Tips
- If clients always check a structure’s value, we separate this check into a special-case.
- NullObject is a common pattern for null value.
- Add the special-case check property to the target structure. Use Combine Functions into Class or Combine Functions into Transform to move the special-case logic into a new class. Then the previous special-case check property will return it when check triggers.
Examples:
- A Class example
- An Object Literal example
- A Transform example
Github
Introduce Assertion
Tips
- Assertion definitely marks the assumption(expression). Assertion avoid programmer’s error.
- Don’t abuse assertion. We only use it when the expression must be true.
Examples:
// before refactoring
public void SaveMoneyIntoAccount(decimal money)
{
acount += money;
}
// after refactoring
public void SaveMoneyIntoAccount(decimal money)
{
Debug.Assert(money > 0);
acount += money;
}
Conclusion
This chapter introduces me how to simplify conditional logic. I had ever written complex conditional branches and they were very ugly long…… I had no idea to reafactor them until I read this chapter. If you want to learn detailed motivation and mechanics, study the chapter 10 ” Simplifying Conditional Logic ” of Refactoring: Improving the Design of Existing Code (2nd Edition). and it improves our programmer’s ability.